package cn.lblbc.downloadlib;

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;

/**
 * 分片下载器 - 分片级下载执行器，基于网络库发起 Range 请求
 */
public class ChunkDownloader {
    private OkHttpClient mHttpClient;

    public ChunkDownloader() {
        mHttpClient = new OkHttpClient();
    }

    /**
     * 下载分片数据
     * @param chunk 分片信息
     * @param fileUrl 文件下载地址
     * @param tempFilePath 临时文件路径
     * @throws IOException IO异常
     */
    public void downloadChunk(DownloadChunk chunk, String fileUrl, String tempFilePath) throws IOException {
        // 计算还需要下载的字节数
        long remainingBytes = (chunk.getEndPos() - chunk.getStartPos() + 1) - chunk.getDownloadedSize();
        
        if (remainingBytes <= 0) {
            // 分片已经下载完成
            return;
        }
        
        // 构造Range请求头，从已下载的位置继续下载
        long startByte = chunk.getStartPos() + chunk.getDownloadedSize();
        String rangeHeader = "bytes=" + startByte + "-" + chunk.getEndPos();
        
        // 创建请求
        Request request = new Request.Builder()
                .url(fileUrl)
                .header("Range", rangeHeader)
                .build();
        
        // 发起请求
        Response response = mHttpClient.newCall(request).execute();
        if (!response.isSuccessful()) {
            throw new IOException("Failed to download chunk: " + response.code() + " " + response.message());
        }
        
        // 写入文件
        writeResponseToFile(response, tempFilePath, chunk.getStartPos() + chunk.getDownloadedSize());
    }
    
    /**
     * 将响应数据写入文件指定位置
     * @param response HTTP响应
     * @param filePath 文件路径
     * @param startPosition 写入起始位置
     * @throws IOException IO异常
     */
    private void writeResponseToFile(Response response, String filePath, long startPosition) throws IOException {
        File file = new File(filePath);
        if (!file.exists()) {
            file.createNewFile();
        }
        
        try (InputStream inputStream = response.body().byteStream();
             RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw")) {
            
            // 定位到写入位置
            randomAccessFile.seek(startPosition);
            
            byte[] buffer = new byte[8192];
            int bytesRead;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                randomAccessFile.write(buffer, 0, bytesRead);
            }
        }
    }
}